package com.yawn.zerodefect.service;

import com.yawn.zerodefect.util.Constant;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

@Service
public class GraphService {

    @Resource
    private ProcessEngineConfiguration configuration;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;

    private static final String GRAPH_FONT_FAMILY = "仿宋";

    public InputStream process(String id) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
        List<String> highLightedList = getFinishedActivityList(processInstance.getId());
        return graph(processInstance.getProcessDefinitionId(), highLightedList);
    }

    public InputStream task(String id) {
        Task task = taskService.createTaskQuery().taskId(id).singleResult();
        List<String> highLightedList = getActiveActivityIds(task.getExecutionId());
        return graph(task.getProcessDefinitionId(), highLightedList);
    }

    public InputStream graph() {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(Constant.PD_KEY_ZERO_DEFECT).list().get(0);
        return graph(processDefinition.getId());
    }

    private InputStream graph(String processDefinitionId) {
        return graph(processDefinitionId, Collections.emptyList());
    }

    private InputStream graph(String processDefinitionId, List<String> highLightedActivityIds) {
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//        Process mainProcess = bpmnModel.getMainProcess();
//        Collection<FlowElement> flowElements = mainProcess.getFlowElements();
//        List<String> flowList = new ArrayList();
//        for (FlowElement flowElement : flowElements) {
//            flowList.add(flowElement.getId());
//        }
        ProcessDiagramGenerator diagramGenerator = configuration.getProcessDiagramGenerator();
        // 空列表使用Collections.emptyList()，传null必报错
        return diagramGenerator.generateDiagram(bpmnModel, "jpg", highLightedActivityIds, Collections.emptyList(),
                GRAPH_FONT_FAMILY, GRAPH_FONT_FAMILY, GRAPH_FONT_FAMILY, null, 1.0);
    }

    private List<String> getFinishedActivityList(String processInstanceId) {
        List<String> highLightedList = new ArrayList<>();
        List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).list();
        for (HistoricActivityInstance instance : activityInstanceList) {
            highLightedList.add(instance.getActivityId());
        }
        return highLightedList;
    }

    private List<String> getActiveActivityIds(String executionId) {
        return runtimeService.getActiveActivityIds(executionId);
    }
}
